package com.jt.www.common.controller;

import com.jt.www.admin.market.service.MarketerInfoService;
import com.jt.www.admin.order_pc.service.ApplicationFormService;
import com.jt.www.biz.order_pc.service.EndorseService;
import com.jt.www.common.service.EPolicyService;
import com.jt.www.dao.mapper.endorse.SaveEndorseParamMapper;
import com.jt.www.domain.dto.ExcelFileDetailEntity;
import com.jt.www.domain.dto.ExcelFileEntity;
import com.jt.www.domain.dto.ExcelFileOutputDto;
import com.jt.www.domain.enums.common.IsOrNotEnum;
import com.jt.www.domain.enums.common.parser.ReturnType;
import com.jt.www.domain.enums.common.parser.SaveType;
import com.jt.www.enums.endorse.GradeEnum;
import com.jt.www.enums.endorse.InsuranceObjectsEnum;
import com.jt.www.enums.endorse.PolicyTypeEnum;
import com.jt.www.model.param.endorse.AppDetailProParam;
import com.jt.www.model.param.endorse.SaveEndorseParam;
import com.jt.www.model.pay.BizResQo;
import com.jt.www.model.remote.ins.InsManagerResultVO;
import com.jt.www.model.reps.GenericDataResponse;
import com.jt.www.model.reps.GenericListResponse;
import com.jt.www.model.reps.ResponseData;
import com.jt.www.model.vo.InsManagerQo;
import com.jt.www.model.vo.endorse.DetailVo;
import com.jt.www.model.vo.endorse.ParserResultVo;
import com.jt.www.remote.ParserClient;
import com.jt.www.remote.ins.InsClient;
import com.jt.www.util.RemoteFileUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.List;
import java.util.Map;

/**
 * 开发人员使用的工具类
 *
 * @author shaoyn
 */
@Api(value = "工具接口", tags = {"TOOL"}, description = "工具接口")
@RestController
@RequestMapping(value = "/tool")
public class ToolController {

    public static final Logger log = LoggerFactory.getLogger(ToolController.class);
    private static final String INS_FILE = "C:\\Users\\terminal\\Desktop\\annex\\ins.sql";
    private static final String PARSER_FILE = "C:\\Users\\terminal\\Desktop\\annex\\parser.sql";
    @Autowired
    private EPolicyService ePolicyService;
    @Autowired
    private SaveEndorseParamMapper endorseParamMapper;
    @Autowired
    private EndorseService endorseService;
    @Autowired
    private MarketerInfoService marketerInfoService;
    @Autowired
    private ApplicationFormService applicationFormService;
    @Autowired
    private InsClient insClient;
    @Autowired
    private ParserClient parserClient;

    public static void writeFile(String file, String conent) {
        BufferedWriter out = null;
        try {
            out = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(file, true)));
            out.newLine();
            out.write(conent);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 查询产品属性
     *
     * @param appCode
     * @return
     */
    @ApiOperation(value = "更新定时下载电子保单次数", notes = "更新定时下载电子保单次数", httpMethod = "GET")
    @GetMapping(value = "/updateEPolicyTimes")
    public ResponseEntity updateEPolicyTimes(@ApiParam(value = "投保单号", required = true) @RequestParam(value = "appCode") String appCode) {

        String result = ePolicyService.updateEPolicyTimes(appCode);
        return GenericDataResponse.okWithData(result);
    }

    /**
     * 出单后重新下载人员清单
     */
    @ApiOperation(value = "出单后重新下载人员清单", notes = "出单后重新下载人员清单", httpMethod = "GET")
    @GetMapping(value = "/insuranceEffect", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity insuranceEffect(Long id) throws Exception {
        Weekend<SaveEndorseParam> weekend = new Weekend<>(SaveEndorseParam.class);
        WeekendCriteria<SaveEndorseParam, Object> criteria = weekend.weekendCriteria();
        criteria.andEqualTo(SaveEndorseParam::getId, id);
        criteria.andEqualTo(SaveEndorseParam::getIsDeleted, IsOrNotEnum.NO.getValue());
        List<SaveEndorseParam> saveEndorseParams = endorseParamMapper.selectByExample(weekend);
        if (CollectionUtils.isEmpty(saveEndorseParams)) {
            return GenericDataResponse.errorWithMsg("无清单数据!");
        }
        String findCode = "Tool_InsuranceEndorseEffect_" + System.currentTimeMillis();
        //如果是投保单
        if (1 == saveEndorseParams.get(0).getIsIns()) {
            endorseService.insuranceEffect(findCode, saveEndorseParams);
        } else {
            endorseService.endorseEffect(findCode, saveEndorseParams);
        }
        return GenericDataResponse.ok();
    }

    /**
     * 同步私保用户
     */
    @ApiOperation(value = "同步私保用户", notes = "同步私保用户", httpMethod = "GET")
    @GetMapping(value = "/marketerEffect", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity marketerEffect() throws Exception {
        marketerInfoService.marketerEffect();
        return GenericDataResponse.ok();
    }

    /**
     * 将生产上上传清单至测试环境的 错误数据处理并生成sql
     */
    @ApiOperation(value = "处理生产人员清单(不用)", notes = "处理生产人员清单(不用)", httpMethod = "POST")
    @PostMapping(value = "/processAnnexParser", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity processAnnexParser(@RequestBody InsManagerQo insManagerQo) throws Exception {
        String findCode = "processAnnexParser_" + System.currentTimeMillis();

        List<FileChange> fileChanges = Lists.newArrayList();
        //查询投保单列表
        ResponseData responseData = applicationFormService.findApplicationForm(insManagerQo, findCode, false);
        List<InsManagerResultVO> insManagerResultVOS = responseData.getList();
        StringBuffer insSql = new StringBuffer();
        StringBuffer parserSql = new StringBuffer();

        for (InsManagerResultVO insManagerResultVO : insManagerResultVOS) {
            String detailFindCode = findCode + insManagerResultVO.getAppCode();
            //取出清单id
            PolicyTypeEnum policyTypeEnum = PolicyTypeEnum.getByProductCode(insManagerResultVO.getProductCode());
            List<String> fileIds = getFileIds(insManagerResultVO, policyTypeEnum);
            for (String fileId : fileIds) {
                //从测试环境下载
                MultipartFile file = RemoteFileUtils.downloadFile(fileId, insManagerResultVO.getAppCode());
                if (null == file) {
                    log.error("{}------> {}下载失败!", detailFindCode, fileId);
                    continue;
                }
                //上传到生产上模拟前端解析
                ResponseEntity<GenericDataResponse<ParserResultVo>> responseEntity =
                        parserClient.analysisExcelByFile(file, policyTypeEnum.getModelCode(), ReturnType.SUMMARY, SaveType.ALL, "edu");
                ParserResultVo data = responseEntity.getBody().getData();
                if (null == data && policyTypeEnum == PolicyTypeEnum.TRAINEE_SCH) {
                    policyTypeEnum = PolicyTypeEnum.TRAINEE_ENT;
                    responseEntity =
                            parserClient.analysisExcelByFile(file, policyTypeEnum.getModelCode(), ReturnType.SUMMARY, SaveType.ALL, "edu");
                    data = responseEntity.getBody().getData();

                }
                if (null == data || StringUtils.isBlank(data.getFileId())) {
                    log.error("{}------> {} 上传解析失败!", detailFindCode, fileId);
                    throw new Exception("上传解析失败");
                }
                fileChanges.add(new FileChange(fileId, data.getFileId()));
                //生成投保中心需要修改的sql(通过不同的险种生产的sql不一样)
                if (policyTypeEnum == PolicyTypeEnum.TRAINEE_ENT
                        || policyTypeEnum == PolicyTypeEnum.TRAINEE_SCH
                        || policyTypeEnum == PolicyTypeEnum.STUDENT_SCH) {
                    String sql = createUpdateObjectExtendSql(insManagerResultVO.getAppCode(), fileId, data.getFileId());
                    writeFile(INS_FILE, sql);
                }
                String sql2 = createUpdateBizResSql(insManagerResultVO.getAppCode(), fileId, data.getFileId());
                writeFile(INS_FILE, sql2);
                //生产清单服务需要修改的sql
                String annexSql = createAnnexParserSql(fileId, data.getFileId());
                writeFile(PARSER_FILE, annexSql);
            }
            //批单暂时不处理
        }
        return GenericDataResponse.okWithData(fileChanges);
    }

    private List<String> getFileIds(InsManagerResultVO insManagerResultVO, PolicyTypeEnum policyTypeEnum) throws Exception {
        List<String> fileIds = Lists.newArrayList();
        String appCode = insManagerResultVO.getAppCode();
        AppDetailProParam p = new AppDetailProParam();
        p.setAppCode(appCode);
        p.setChannelCode("edu");    // 渠道编号
        p.setUserCode(insManagerResultVO.getHolderCode());

        if (policyTypeEnum == PolicyTypeEnum.TRAINEE_ENT
                || policyTypeEnum == PolicyTypeEnum.TRAINEE_SCH
                || policyTypeEnum == PolicyTypeEnum.STUDENT_SCH) {
            // 实责、校责
            ResponseEntity<GenericListResponse<DetailVo>> appDetailPro = insClient.insuranceObjects(appCode);
            List<DetailVo> detailVos = appDetailPro.getBody().getList();
            for (DetailVo detailVo : detailVos) {
                String fileId = null;
                String grade = null;

                List<Map<String, Object>> extendsList = detailVo.getExtendsList();
                for (Map<String, Object> fields : extendsList) {
                    if (fileId != null && grade != null) {
                        break;
                    }
                    if (InsuranceObjectsEnum.FILE_ID.getCode().equals(fields.get("fieldCode"))) {
                        fileId = (String) fields.get("fieldValues");
                    }
                    if (InsuranceObjectsEnum.GRADE.getCode().equals(fields.get("fieldCode"))) {
                        String englishGrade = (String) fields.get("fieldValues");
                        grade = GradeEnum.getMsgByEnCode(englishGrade);
                    }
                }
                if (fileId != null) {
                    fileIds.add(fileId);
                }
            }
        } else {
            // 山东、云南、学责
            ResponseEntity<GenericListResponse<Map<String, String>>> resources;
            List<Map<String, String>> results;
            BizResQo bizResQo = new BizResQo();
            bizResQo.setAppCode(appCode);
            bizResQo.setBizCodeType("04");
            bizResQo.setResCode("A101");
            resources = insClient.getResources(bizResQo);
            results = resources.getBody().getList();
            if (CollectionUtils.isNotEmpty(results)) {
                for (Map<String, String> result : results) {
                    String fileId = result.get("resId");
                    if (fileId == null) {
                        continue;
                    }
                    fileIds.add(fileId);
                }
            }
        }
        return fileIds;
    }

    private String createUpdateObjectExtendSql(String appCode, String oldFileId, String newFileId) {
        return "UPDATE t_application_form af LEFT JOIN t_insured i " +
                "ON i.t_application_form_id = af.id LEFT JOIN t_insurance_object io " +
                "ON io.t_insured_info_id = i.id LEFT JOIN t_insurance_object_extend ioe " +
                "ON ioe.t_insurance_object_id = io.id AND ioe.field_code = 'S_O_000031' " +
                "SET ioe.field_values = '" + newFileId + "' WHERE  af.application_form_code = '" + appCode + "' AND ioe.field_values = '" + oldFileId + "';";
    }

    private String createUpdateBizResSql(String appCode, String oldFileId, String newFileId) {
        return "UPDATE t_application_form af LEFT JOIN t_biz_res br ON br.biz_code = af.id " +
                "SET res_id = '" + newFileId + "' WHERE af.application_form_code = '" + appCode + "' and res_id = '" + oldFileId + "';";
    }

    private String createAnnexParserSql(String oldFileId, String newFileId) {
        return "update t_excel_file set file_id='" + newFileId + "' where file_id='" + oldFileId + "';";
    }

    /**
     * 将生产上上传清单至测试环境的 错误数据处理并生成sql
     */
    @ApiOperation(value = "处理生产人员清单", notes = "处理生产人员清单", httpMethod = "POST")
    @PostMapping(value = "/processAnnexParser_new", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity processAnnexParser_new(@RequestBody InsManagerQo insManagerQo) throws Exception {
        String findCode = "processAnnexParser_new_" + System.currentTimeMillis();

        List<String> fileChanges = Lists.newArrayList();
        //查询投保单列表
        ResponseData responseData = applicationFormService.findApplicationForm(insManagerQo, findCode, false);
        List<InsManagerResultVO> insManagerResultVOS = responseData.getList();

        int id = 50000;
        for (InsManagerResultVO insManagerResultVO : insManagerResultVOS) {
            String detailFindCode = findCode + insManagerResultVO.getAppCode();
            //取出清单id
            PolicyTypeEnum policyTypeEnum = PolicyTypeEnum.getByProductCode(insManagerResultVO.getProductCode());
            List<String> fileIds = getFileIds(insManagerResultVO, policyTypeEnum);
            for (String fileId : fileIds) {
                //上传到生产上模拟前端解析
                ResponseEntity<GenericDataResponse<ExcelFileOutputDto>> responseEntity =
                        parserClient.excelFileDtoList(fileId);
                ExcelFileOutputDto data = responseEntity.getBody().getData();
                if (null == data) {
                    log.error("查询失败" + insManagerResultVO.getAppCode());
                    throw new Exception("查询失败" + insManagerResultVO.getAppCode());
                }
                ExcelFileEntity excelFile = data.getExcelFile();
                writeFile(PARSER_FILE, createExcelFileSql(++id, excelFile));
                //生产清单服务需要修改的sql
                for (ExcelFileDetailEntity excelFileDetail : data.getExcelFileDetail()) {
                    writeFile(PARSER_FILE, createExcelFileDetailSql(id, excelFileDetail));
                }
                fileChanges.add(fileId);
            }

            //批单暂时不处理
        }
        return GenericDataResponse.okWithData(fileChanges);
    }

    private String createExcelFileSql(Integer id, ExcelFileEntity excelFileEntity) {
        return "INSERT INTO `t_excel_file`(`id`, `file_id`, `channel_code`, `file_name`, `count_designated`) " +
                "VALUES ('" + id + "', '" + excelFileEntity.getFileId() + "', '" + excelFileEntity.getChannelCode() + "', '" + excelFileEntity.getFileName() + "', '" + excelFileEntity.getCountDesignated() + "');";
    }

    private String createExcelFileDetailSql(Integer exceclFileId, ExcelFileDetailEntity excelFileDetailEntity) {
        return "INSERT INTO `t_excel_file_detail`(`excel_file_id`, `field1`, `field2`, `field3`, `content`) " +
                "VALUES ( '" + exceclFileId + "', '" + excelFileDetailEntity.getField1() + "', '" + excelFileDetailEntity.getField2() + "', '" + excelFileDetailEntity.getField3() + "', '" + excelFileDetailEntity.getContent() + "');";
    }

    /**
     * 将生产上上传清单至测试环境的 文件url生成下载sql
     */
    @ApiOperation(value = "处理生产人员清单生成下载文件url", notes = "处理生产人员清单生成下载文件url", httpMethod = "POST")
    @PostMapping(value = "/processAnnexParserCreateUrl", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity processAnnexParserCreateUrl(@RequestBody InsManagerQo insManagerQo) throws Exception {
        String findCode = "processAnnexParserCreateUrl" + System.currentTimeMillis();

        List<String> fileChanges = Lists.newArrayList();
        //查询投保单列表
        ResponseData responseData = applicationFormService.findApplicationForm(insManagerQo, findCode, false);
        List<InsManagerResultVO> insManagerResultVOS = responseData.getList();

        int id = 50000;
        for (InsManagerResultVO insManagerResultVO : insManagerResultVOS) {
            //取出清单id
            PolicyTypeEnum policyTypeEnum = PolicyTypeEnum.getByProductCode(insManagerResultVO.getProductCode());
            List<String> fileIds = getFileIds(insManagerResultVO, policyTypeEnum);
            for (String fileId : fileIds) {
                String sql;
                // 实责、校责
                if (policyTypeEnum == PolicyTypeEnum.TRAINEE_ENT
                        || policyTypeEnum == PolicyTypeEnum.TRAINEE_SCH
                        || policyTypeEnum == PolicyTypeEnum.STUDENT_SCH) {
                    sql = "http://gw-test.jiangtai.com/_gw/jtpf/res-svc/res/v3/download?applicationName=ins-svc&businessTypeCode=ins_obj&businessDataTag=" + insManagerResultVO.getAppCode() + "&free=0&fileId=" + fileId;
                } else {
                    sql = "http://gw-test.jiangtai.com/_gw/jtpf/res-svc/res/v3/download?applicationName=ins-svc&businessTypeCode=ins_app&businessDataTag=" + insManagerResultVO.getAppCode() + "&free=0&fileId=" + fileId;
                }
            }
            //批单暂时不处理
        }
        return GenericDataResponse.okWithData(fileChanges);
    }

    class FileChange {
        String oldFileId;
        String newFileId;

        public FileChange(String oldFileId, String newFileId) {
            this.oldFileId = oldFileId;
            this.newFileId = newFileId;
        }

        public String getOldFileId() {
            return this.oldFileId;

        }

        public void setOldFileId(String oldFileId) {
            this.oldFileId = oldFileId;
        }

        public String getNewFileId() {
            return this.newFileId;

        }

        public void setNewFileId(String newFileId) {
            this.newFileId = newFileId;
        }
    }
}
